﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;

namespace Exocortex.Excel.Nuget
{
    public static class PackageManagerModule
    {
        private static readonly IEnumerable<WebPackageSource> _defaultSources;
        private static ISet<WebPackageSource> _packageSources;
        private static readonly PackageSourceFile _sourceFile;
        private static readonly object _sourceFileLock = new object();
        private const string DefaultSourceUrl = "http://go.microsoft.com/fwlink/?LinkID=206971";
        private const string NuGetSourceUrl = "http://go.microsoft.com/fwlink/?LinkID=206669";
        public static readonly string PackageSourceFilePath = VirtualPathUtility.Combine("~/App_Data/Admin/", "PackageSources.config");

        static PackageManagerModule()
        {
            string defaultPackageSourceName = "DefaultPackageSourceName"; // PackageManagerResources.DefaultPackageSourceName;
            string str2 = "http://go.microsoft.com/fwlink/?LinkID=206971";
            string nuGetFeed = "NuGetFeed"; // PackageManagerResources.NuGetFeed;
            string str4 = "http://go.microsoft.com/fwlink/?LinkID=206669";

            WebPackageSource[] sourceArray = new WebPackageSource[2];

            WebPackageSource source = new WebPackageSource(str2, defaultPackageSourceName);
            source.FilterPreferredPackages = true;
            sourceArray[0] = source;
            WebPackageSource source2 = new WebPackageSource(str4, nuGetFeed);
            source2.FilterPreferredPackages = false;
            sourceArray[1] = source2;
            _defaultSources = sourceArray;
            _sourceFile = new PackageSourceFile(PackageSourceFilePath);
        }

        public static bool AddPackageSource(WebPackageSource packageSource)
        {
            return AddPackageSource(_sourceFile, _packageSources, packageSource);
        }

        public static bool AddPackageSource(string source, string name)
        {
            name = string.IsNullOrEmpty(name) ? source.ToString() : name;
            string str = source;
            string str2 = name;
            WebPackageSource packageSource = new WebPackageSource(str, str2);
            return AddPackageSource(_sourceFile, _packageSources, packageSource);
        }

        public static bool AddPackageSource(IPackagesSourceFile sourceFile, ISet<WebPackageSource> packageSources, WebPackageSource packageSource)
        {
            if (GetSource(packageSources, packageSource.Name) != null)
            {
                return false;
            }
            lock (_sourceFileLock)
            {
                packageSources.Add(packageSource);
                sourceFile.WriteSources(packageSources);
            }
            return true;
        }

        public static WebPackageSource GetSource(string sourceName)
        {
            return GetSource(PackageSources, sourceName);
        }

        public static WebPackageSource GetSource(IEnumerable<WebPackageSource> packageSources, string sourceName)
        {
            Func<WebPackageSource, bool> predicate = null;
            lock (_sourceFileLock)
            {
                if (predicate == null)
                {
                    predicate = delegate(WebPackageSource source)
                    {
                        return source.Name.Equals(sourceName, StringComparison.OrdinalIgnoreCase);
                    };
                }
                return packageSources.Where<WebPackageSource>(predicate).FirstOrDefault<WebPackageSource>();
            }
        }

        public static bool InitPackageSourceFile()
        {
            return InitPackageSourceFile(_sourceFile, ref _packageSources);
        }

        public static bool InitPackageSourceFile(IPackagesSourceFile sourceFile, ref ISet<WebPackageSource> packageSources)
        {
            if (packageSources == null)
            {
                try
                {
                    lock (_sourceFileLock)
                    {
                        if (!sourceFile.Exists())
                        {
                            packageSources = new HashSet<WebPackageSource>(_defaultSources);
                            sourceFile.WriteSources(_packageSources);
                        }
                        else
                        {
                            packageSources = new HashSet<WebPackageSource>(sourceFile.ReadSources());
                        }
                    }
                }
                catch
                {
                    return false;
                }
            }
            return true;
        }

        public static void RemovePackageSource(string sourceName)
        {
            RemovePackageSource(_sourceFile, _packageSources, sourceName);
        }

        public static void RemovePackageSource(IPackagesSourceFile sourceFile, ISet<WebPackageSource> packageSources, string name)
        {
            WebPackageSource item = GetSource(packageSources, name);
            lock (_sourceFileLock)
            {
                if (item != null)
                {
                    packageSources.Remove(item);
                    sourceFile.WriteSources(packageSources);
                }
            }
        }

        public static WebPackageSource ActiveSource
        {
            get
            {
                return PackageSources.First<WebPackageSource>();
            }
        }

        // può essere utile
        public static bool Available
        {
            get
            {
                return ((HttpContext.Current != null) && HttpContext.Current.Request.IsLocal);
            }
        }

        public static IEnumerable<WebPackageSource> DefaultSources
        {
            get
            {
                return _defaultSources;
            }
        }

        //public static string ModuleDescription
        //{
        //    get
        //    {
        //        return "ModuleDescription"; //PackageManagerResources.ModuleDesc;
        //    }
        //}

        //public static string ModuleName
        //{
        //    get
        //    {
        //        return "ModuleName"; //PackageManagerResources.ModuleTitle;
        //    }
        //}

        public static IEnumerable<WebPackageSource> PackageSources
        {
            get
            {
                if (!_packageSources.Any<WebPackageSource>())
                {
                    return _defaultSources;
                }
                return _packageSources;
            }
        }

        public static string SiteRoot
        {
            get
            {
                return HostingEnvironment.MapPath("~/");
            }
        }
    }
}

